﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Linq.Expressions;
using System.Collections;

namespace Puzzles_IQ
{
   

    class Locations
    {
        private int complexity;
        private int arrSize;
        private Point initialLocation;
        private Size blockSize;
        private Point[] defaultLocs, mixedLocs; // Locs = Locations
        private Rectangle[] stickers;
        public Point potentialLocation;

        #region Constructors

        public Locations(Size s, Complexity c)
        {
            initialLocation = new Point(20, 35);
            blockSize = s;
            complexity = (int)c;
            arrSize = complexity * complexity;
            defaultLocs = new Point[arrSize];
            mixedLocs = new Point[arrSize];
            stickers = new Rectangle[arrSize];

        }

        public Locations(Point initialLocation, Size s, Complexity c)
        {
            this.initialLocation = initialLocation;
            blockSize = s;
            complexity = (int)c;
            arrSize = complexity * complexity;
            defaultLocs = new Point[arrSize];
            mixedLocs = new Point[arrSize];
            stickers = new Rectangle[arrSize];
        }

        #endregion


        public Point[] SetInitialPoints()
        {
            Point initloc = initialLocation;

            for (int i = 0, x = 0; i < complexity; i++)
            {
                for (int j = 0; j < complexity; j++)
                {
                    defaultLocs[x].X = initloc.X;
                    defaultLocs[x].Y = initloc.Y;

                    initloc.X += blockSize.Width + 1; //+1 x-space between puzzles
                    x++;
                }
                initloc.X = initialLocation.X;
                initloc.Y += blockSize.Height + 1; //+1 y-space between puzzles
            }

            return defaultLocs;
        }

        public Rectangle[] GenerateStickers()
        {
            int x = 0;
            foreach(Point l in defaultLocs)
            {
                stickers[x++] = new Rectangle(l.X + 5, l.Y + 5, blockSize.Width - 10, blockSize.Height - 10);
            }
            return stickers;
        }

        public Point[] MixPoints()
        {
            Point ptemp;
            Random rnd = new Random();
            //
            defaultLocs.CopyTo(mixedLocs, 0);
            //
            for (int i = 0, temp = 0; i < arrSize; i++)
            {
                temp = rnd.Next(arrSize);
                ptemp = mixedLocs[i];
                mixedLocs[i] = mixedLocs[temp];
                mixedLocs[temp] = ptemp;
            }

            return mixedLocs;
        }

        public Point[] Move(Direction dir)
        {
            Point[] newMixedLocs = new Point[arrSize];
            int margin = defaultLocs[arrSize - 1].X + blockSize.Width + 50;

            var mixed = from x in mixedLocs
                        select new Point { X = x.X += margin, Y = x.Y };

            newMixedLocs = mixed.ToArray();

            return newMixedLocs;

        }

        public bool IsFreePlace(Point p, Size s, List<Point> pblocs)
        {
            bool isfree = false;
            Point pbcenter = new Point(p.X + (s.Width / 2), p.Y + (s.Height / 2));
            int x = 0;
            foreach (Rectangle sticker in GenerateStickers())
            {
                if (sticker.Contains(pbcenter))
                { 
                    if (IsPlaceOccupied(defaultLocs[x], pblocs) == false)
                    {
                        isfree = true;
                        break;
                    }
                    else
                        continue;
                }
                x++;
            }
            return isfree;
        }

        public bool IsPlaceOccupied(Point potentialLocation, List<Point> pbLocs)
        {
            bool placeOccupied = false;

            foreach (Point pbLoc in pbLocs)
            {
                if (pbLoc == potentialLocation)
                {
                    placeOccupied = true;
                    break;
                }
            }
            this.potentialLocation = potentialLocation;
            return placeOccupied;
        }

        public bool IsWinner(List<Point> l)
        {
            int wincount = 0;

            for (int i = 0; i < arrSize; i++)
            {
                if (l[i] == defaultLocs[i])
                {
                    wincount++;
                }
            }
            //
            if (wincount == arrSize)
            {
                return true;
            }
            else
                return false;
        
        }


    }
}
